package com.ocom.exposeapi.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.ExposeApiUrl;
import com.ocom.common.constant.MapKey;
import com.ocom.common.entity.access.EntityDeptInfo;
import com.ocom.common.entity.card.EntityCardInfo;
import com.ocom.common.entity.card.EntityXfDeviceInfo;
import com.ocom.common.entity.company.EntityComDockApi;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.enums.*;
import com.ocom.common.request.company.GetReplyApiParaRequest;
import com.ocom.common.request.exposeapi.*;
import com.ocom.common.request.payconfig.AddCardInfoVo;
import com.ocom.common.request.payhandle.FeeRefundRequest;
import com.ocom.common.request.payhandle.QrCardPayRequest;
import com.ocom.common.request.payhandle.QrCodeQueryRequest;
import com.ocom.common.request.payhandle.QrCodeRefundRequest;
import com.ocom.common.request.simple.GzhMsgParam;
import com.ocom.common.request.simple.GzhMsgRequest;
import com.ocom.common.resp.RespMachMessage;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.utils.SignUtils;
import com.ocom.common.vo.PersonVo;
import com.ocom.common.vo.human.UserInfoVo;
import com.ocom.common.vo.human.UserInfoVo2;
import com.ocom.common.vo.human.XfUserInfoVo;
import com.ocom.common.vo.pay.UpdateListRechargeVo;
import com.ocom.common.vo.payconfig.UpdatecardStateVo;
import com.ocom.exposeapi.feign.*;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: TODO
 * @Author: 朱晖
 * @Date: 2023/3/21
 **/
@Slf4j
@RestController
public class GkdController {

	@Autowired
	private CompanyClientService companyClientService;

	@Autowired
	private HumanFeignService humanFeignService;

	@Autowired
	private PayConfigClientService payConfigClientService;

	@Autowired
	private PayHandleClientService payHandleClientService;

	@Autowired
	private MqSimple mqSimple;

	@Autowired
	private  RedissonClient redissonClient;

	@Autowired
	private XfRecordFeign xfRecordFeign;

	@Resource
	private RedisUtil redisUtil;


	@Value("${spring.redis.rateLimit:2}")
	private String rateLimit;

	//4.1.1账户充值（gkd#recharge）
	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdAccountRecharge)
	public Result accountRecharge(@Validated @RequestBody AccountRechargeRequest request, BindingResult bindingResult) {

		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid(request.getComId());
		getReplyApiParaRequest.setDockCode("gkd");
		getReplyApiParaRequest.setDockApiCode("gkd#recharge");
		getReplyApiParaRequest.setKeyType(0);
		Result result = companyClientService.getReplyApiPara(getReplyApiParaRequest);
		if (result.getCode() != 200) {
			return result;
		}

		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result.getData()), EntityComDockApi.class);


		
		String sign = request.getSign().toLowerCase();
		request.setSign("");
		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(request), SortedMap.class);
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		System.out.println(sign1);
		if (!sign.equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}

		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setComId(entityComDockApi.getComId());
		userInfoVo.setPCode(request.getPCode());
		userInfoVo.setOnlyOne(true);
		Result result1 = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
		if (result1.getCode() != 200) {
			return result1;
		}
		EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result1.getData()), EntityPersonnelInfo.class);

		UpdateListRechargeVo updateListRechargeVo = new UpdateListRechargeVo();
		updateListRechargeVo.setComId(entityComDockApi.getComId());
		updateListRechargeVo.setPId(entityPersonnelInfo.getPId());
		updateListRechargeVo.setRechargeMoney(request.getMoney());
		updateListRechargeVo.setFrom(2);
		updateListRechargeVo.setOrderNo(request.getOrderNo());
		updateListRechargeVo.setDockApiCode(entityComDockApi.getDockApiCode());
		updateListRechargeVo.setDockApiName(entityComDockApi.getApiName());

		if (request.getType() == 1) {
			updateListRechargeVo.setTypeNo(1);
			updateListRechargeVo.setTypeName("现金");
			updateListRechargeVo.setRemark("现金充值:" + request.getMoney() + "分");
		}
		if (request.getType() == 2) {
			updateListRechargeVo.setTypeNo(2);
			updateListRechargeVo.setTypeName("补贴");
			updateListRechargeVo.setRemark("补贴充值:" + request.getMoney() + "分");
		}
		if (request.getType() == 3) {
			updateListRechargeVo.setTypeNo(3);
			updateListRechargeVo.setTypeName("奖金");
			updateListRechargeVo.setRemark("奖金充值:" + request.getMoney() + "分");
		}
		Result result2 = payConfigClientService.UpdateListRecharge(updateListRechargeVo);

		if (result2.getCode() != 200) {
			return result2;
		}
		JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(result2.getData()));

		jsonObject.put("pCode", entityPersonnelInfo.getPCode());
		jsonObject.put("pName", entityPersonnelInfo.getPName());

		return ResultUtil.success(jsonObject);
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdAddPerson)
	public Result addPerson(@Validated @RequestBody AddPersonRequest request, BindingResult bindingResult) {

		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid(request.getComId());
		getReplyApiParaRequest.setDockCode("gkd");
		getReplyApiParaRequest.setDockApiCode("gkd#addPerson");
		getReplyApiParaRequest.setKeyType(0);
		Result result = companyClientService.getReplyApiPara(getReplyApiParaRequest);
		if (result.getCode() != 200) {
			return result;
		}

		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result.getData()), EntityComDockApi.class);

		String sign = request.getSign().toLowerCase();
		request.setSign("");
		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(request), SortedMap.class);
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		System.out.println(sign1);
		if (!sign.equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}

		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setComId(entityComDockApi.getComId());
		userInfoVo.setPCode(request.getPCode());
		userInfoVo.setOnlyOne(true);
		Result result1 = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
		if (result1.getCode() == 200) {
			return ResultUtil.error(ResultEnum.Err_2035);
		}

		Long deptId = 0l;

		if (!CommonUtil.isNull(request.getDept())) {
			try {
				List<EntityDeptInfo> list = new ArrayList<>();
				//获取完整部门树
				Result result2 = humanFeignService.getDeptList(entityComDockApi.getComId(), 0l, 1);
				if (result2.getCode() != 200) {
					return ResultUtil.error(ResultEnum.Err_302);
				}
				list = JSON.parseArray(JSON.toJSONString(result2.getData()), EntityDeptInfo.class);

				String[] deptNameSplit = request.getDept().split("/");

				Long realDeptId = 0l;
				Long parentDeptId = 0l;
				outterLoop:
				for (String ndeptName : deptNameSplit) {
					Boolean exist = false;
					for (EntityDeptInfo entityDeptInfo : list) {
						//匹配到名称
						if (entityDeptInfo.getDeptName().equals(ndeptName) &&
								entityDeptInfo.getParentDeptId().equals(parentDeptId)) {
							exist = true;
							parentDeptId = entityDeptInfo.getDeptId();
							realDeptId = entityDeptInfo.getDeptId();
							break;
						}
					}
					//匹配不到 跳出循环
					if (!exist) {
						break outterLoop;
					}
				}
				deptId = realDeptId;
			} catch (Exception e) {
				log.info("部门匹配异常【{}】 【{}】", request, e);
			}

		}

		PersonVo personVo = new PersonVo();
		personVo.setComId(entityComDockApi.getComId());
		personVo.setPName(request.getPName());
		personVo.setPCode(request.getPCode());
		personVo.setDeptId(deptId);
		Result result3 = humanFeignService.AddPerson(personVo);

		if (result3.getCode() != 200) {
			return result3;
		}
		EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result3.getData()), EntityPersonnelInfo.class);

		try {
			Map<String, Object> map = new HashMap<>();
			MapKey mapKey = new MapKey();
			map.put(mapKey.getKey_pId(), entityPersonnelInfo.getPId());
			map.put(mapKey.getKey_comId(), entityPersonnelInfo.getComId());
			map.put(mapKey.getKey_accountNo(), entityPersonnelInfo.getComId() + "P" + entityPersonnelInfo.getPId());
			map.put(mapKey.getKey_accountName(), entityPersonnelInfo.getComId() + "P" + entityPersonnelInfo.getPId());
			map.put(mapKey.getKey_accountId(), request.getAccountType());
			map.put(mapKey.getKey_accountState(), 0);
			mqSimple.AddXFAccount(map);
		} catch (Exception e) {
			log.info("添加消费账户异常【{}】 【{}】", request, e);
		}

		return ResultUtil.success();
	}


	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdCardOperation)
	public Result cardOperation(@Validated @RequestBody CardOperationRequest request, BindingResult bindingResult) {

		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid(request.getComId());
		getReplyApiParaRequest.setDockCode("gkd");
		getReplyApiParaRequest.setDockApiCode("gkd#cardOperation");
		getReplyApiParaRequest.setKeyType(0);
		Result result = companyClientService.getReplyApiPara(getReplyApiParaRequest);
		if (result.getCode() != 200) {
			return result;
		}

		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result.getData()), EntityComDockApi.class);

		String sign = request.getSign().toLowerCase();
		request.setSign("");
		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(request), SortedMap.class);
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		System.out.println(sign1);
		if (!sign.equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}

		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setComId(entityComDockApi.getComId());
		userInfoVo.setPCode(request.getPCode());
		userInfoVo.setOnlyOne(true);
		Result result1 = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
		if (result1.getCode() != 200) {
			return result1;
		}
		EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result1.getData()), EntityPersonnelInfo.class);

		//1-发卡，2-退卡，3-挂失，4-解挂

		Result result3 = humanFeignService.getXfUserInfo(entityComDockApi.getComId(), entityPersonnelInfo.getPId());
		if (result3.getCode() != 200) {
			return result3;
		}
		XfUserInfoVo xfUserInfoVo = JSON.parseObject(JSON.toJSONString(result3.getData()), XfUserInfoVo.class);

		if (request.getType() == 1) {

			Result result2 = payConfigClientService.GetCardInfoByPid(entityComDockApi.getComId(), entityPersonnelInfo.getPId());
			if (result2.getCode() != 200) {
				return result2;
			}
			//有卡
			if (result2.getData() != null) {
				EntityCardInfo entityCardInfo = JSON.parseObject(JSON.toJSONString(result2.getData()), EntityCardInfo.class);
				if (entityCardInfo.getCardState() == 1) {
					return ResultUtil.error(ResultEnum.Err_815);
				}
				if (entityCardInfo.getCardState() == 0) {
					return ResultUtil.error(ResultEnum.Err_3105);
				}
			}

			AddCardInfoVo addCardInfoVo = new AddCardInfoVo();
			addCardInfoVo.setComId(entityComDockApi.getComId());
			addCardInfoVo.setAccountNo(entityComDockApi.getComId() + "P" + entityPersonnelInfo.getPId());
			addCardInfoVo.setCardNo(request.getCardNo());
			addCardInfoVo.setDeposit(0l);
			addCardInfoVo.setEndDate("2032-12-12 23:59:59");
			addCardInfoVo.setCostFee(0l);
			addCardInfoVo.setPId(entityPersonnelInfo.getPId());
			addCardInfoVo.setDeptId(xfUserInfoVo.getDeptId());
			addCardInfoVo.setAccTypeId(xfUserInfoVo.getAccTypeId());
			addCardInfoVo.setUser("JK");
			return payConfigClientService.AddCardInfo(addCardInfoVo);
		} else {
			//1-发卡，2-退卡，3-挂失，4-解挂
			UpdatecardStateVo updatecardStateVo = new UpdatecardStateVo();
			updatecardStateVo.setComId(entityComDockApi.getComId());
			updatecardStateVo.setPId(entityPersonnelInfo.getPId());
			updatecardStateVo.setUser("JK");
			updatecardStateVo.setCardNo(request.getCardNo());
			updatecardStateVo.setAccountNo(xfUserInfoVo.getAccountNo());
			if (request.getType() == 2) {
				updatecardStateVo.setCardState(2);
			}
			if (request.getType() == 3) {
				updatecardStateVo.setCardState(0);
			}
			if (request.getType() == 4) {
				updatecardStateVo.setCardState(1);
			}
			return payConfigClientService.UpdatecardState(updatecardStateVo);
		}
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdConsumeDetail)
	public Result consumeDetail(@Validated @RequestBody ConsumeDetailRequest request, BindingResult bindingResult) {

		String dates = DateUtils.dateTime();
		//限流！
		String ipf = dates+":"+request.getComId();

		Set<Object> rangeByScore = redisUtil.rangeByScore("exConsumeDetailLimit:"+ipf , System.currentTimeMillis() - 1000l * 60l, System.currentTimeMillis());

		if (rangeByScore != null &&  rangeByScore.size() > 4) {
			return ResultUtil.error(ResultEnum.Err_3118);
		}
		redisUtil.zAdd("exConsumeDetailLimit:"+ipf, System.currentTimeMillis() , System.currentTimeMillis());

		redisUtil.expire("exConsumeDetailLimit:"+ipf,600l);


		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid(request.getComId());
		getReplyApiParaRequest.setDockCode("gkd");
		getReplyApiParaRequest.setDockApiCode("gkd#consumeDetail");
		getReplyApiParaRequest.setKeyType(0);
		Result result3 = companyClientService.getReplyApiPara(getReplyApiParaRequest);
		if (result3.getCode() != 200) {
			return result3;
		}
		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result3.getData()), EntityComDockApi.class);

		String sign = request.getSign().toLowerCase();
		request.setSign("");
		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(request), SortedMap.class);
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		System.out.println(sign1);
		if (!sign.equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}

		JSONObject jsonObject = new JSONObject();
		
		if(!CommonUtil.isNull(request.getPCode())) {

			UserInfoVo userInfoVo = new UserInfoVo();
			userInfoVo.setComId(entityComDockApi.getComId());
			userInfoVo.setPCode(request.getPCode());
			userInfoVo.setOnlyOne(true);
			Result result1 = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
			if (result1.getCode() != 200) {
				return result1;
			}
			EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result1.getData()), EntityPersonnelInfo.class);
			jsonObject.put("pId", entityPersonnelInfo.getPId());
		}

		Integer year = Integer.valueOf(request.getMonth().substring(0, 4));
		Integer month = Integer.valueOf(request.getMonth().substring(4));

		String lastDay = DateUtils.getLastDayOfMonth(year, month);

		jsonObject.put("comId", entityComDockApi.getComId());
		jsonObject.put("startTime", year + "-" + month + "-" + "01 00:00:00");
		jsonObject.put("endTime", lastDay + " 23:59:59");
		jsonObject.put("page", request.getPage());
		jsonObject.put("size", request.getSize());


		Result result = xfRecordFeign.getConsumeDetail(jsonObject);
		if (result.getCode() == 200) {
			JSONObject reJson = JSON.parseObject(JSON.toJSONString(result.getData()));
			List<JSONObject> list = JSON.parseArray(JSON.toJSONString(reJson.get("list")), JSONObject.class);
			for (JSONObject entityXfRecord : list) {
				entityXfRecord.put("payState", PayStateEnum.getValueByKey(entityXfRecord.getIntValue("payState")));
				entityXfRecord.put("consState", ConsStateEnum.getValueByKey(entityXfRecord.getIntValue("consState")));
				entityXfRecord.put("opTypeDiff", OpTypeDiffEnum.getName(entityXfRecord.getIntValue("opTypeDiff")));
				entityXfRecord.put("opType", OpTypeEnum.getName(entityXfRecord.getIntValue("opType")));
			}
			reJson.put("list", list);
			return ResultUtil.success(reJson);
		}
		return result;
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdOneDayConsumeDetail)
	public Result oneDayConsumeDetail(@Validated @RequestBody OneDayConsumeDetailRequest request, BindingResult bindingResult) {
//		log.info("gkdOneDayConsumeDetail接收的参数：【{}】", JSON.toJSONString(request));
//		RRateLimiter rateLimiter = redissonClient.getRateLimiter("rateLimit:gkdOneDayConsumeDetail");
//		rateLimiter.trySetRate(RateType.OVERALL, Integer.parseInt(this.rateLimit), 1, RateIntervalUnit.MINUTES);

		String dates = DateUtils.dateTime();
		//限流！
		String ipf = dates+":"+request.getComId();

		Set<Object> rangeByScore = redisUtil.rangeByScore("oneDayConsumeDetail:"+ipf , System.currentTimeMillis() - 100l * 600l, System.currentTimeMillis());
		if (rangeByScore != null &&  rangeByScore.size() > 1) {
			return ResultUtil.error(ResultEnum.Err_901);
		}

		redisUtil.zAdd("oneDayConsumeDetail:"+ipf, System.currentTimeMillis() , System.currentTimeMillis());
//		if (!rateLimiter.tryAcquire()) {
//			return ResultUtil.error(ResultEnum.Err_901);
//		}
		redisUtil.expire("oneDayConsumeDetail:"+ipf,600l);


		GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
		getReplyApiParaRequest.setComAppid(request.getComId());
		getReplyApiParaRequest.setDockCode("gkd");
		getReplyApiParaRequest.setDockApiCode("gkd#oneDayConsumeDetail");
		getReplyApiParaRequest.setKeyType(0);
		log.info("gkdOneDayConsumeDetail_getReplyApiPara接收的参数：【{}】", JSON.toJSONString(getReplyApiParaRequest));
		Result result3 = companyClientService.getReplyApiPara(getReplyApiParaRequest);
		if (result3.getCode() != 200) {
			return result3;
		}
		EntityComDockApi entityComDockApi = JSON.parseObject(JSON.toJSONString(result3.getData()), EntityComDockApi.class);

		String sign = request.getSign().toLowerCase();
		request.setSign("");
		SortedMap<String, Object> parameters = JSON.parseObject(JSON.toJSONString(request), SortedMap.class);
		parameters.put("day",DateUtil.formatDate(request.getDay()));
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		System.out.println(sign1);
		if (!sign.equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}


		JSONObject jsonObject = new JSONObject();
		jsonObject.put("comId", entityComDockApi.getComId());


		jsonObject.put("startTime", DateUtil.formatDateTime(DateUtil.beginOfDay(request.getDay())));
		jsonObject.put("endTime",DateUtil.formatDateTime(DateUtil.endOfDay(request.getDay())));
		jsonObject.put("page", request.getPage());
		jsonObject.put("size", request.getSize());
		jsonObject.put("id",request.getId());
		jsonObject.put("orderBy","id");

		log.info("gkdOneDayConsumeDetail_getConsumeDetail接收的参数：【{}】", JSON.toJSONString(jsonObject));
		Result result = xfRecordFeign.getConsumeDetail(jsonObject);
		log.info("gkdOneDayConsumeDetail_getConsumeDetail返回的结果：【{}】", JSON.toJSONString(result));
		if (result.getCode() == 200) {
			JSONObject reJson = JSON.parseObject(JSON.toJSONString(result.getData()));
			List<JSONObject> list = JSON.parseArray(JSON.toJSONString(reJson.get("list")), JSONObject.class);
			for (JSONObject entityXfRecord : list) {
				entityXfRecord.put("payState", PayStateEnum.getValueByKey(entityXfRecord.getIntValue("payState")));
				entityXfRecord.put("consState", ConsStateEnum.getValueByKey(entityXfRecord.getIntValue("consState")));
				entityXfRecord.put("opTypeDiff", OpTypeDiffEnum.getName(entityXfRecord.getIntValue("opTypeDiff")));
				entityXfRecord.put("opType", OpTypeEnum.getName(entityXfRecord.getIntValue("opType")));
			}
			Integer maxId = ObjectUtil.isEmpty(list)? request.getId() : list.get(list.size() - 1).getInteger("id");
			reJson.put("list", list);
			reJson.put("maxId",maxId);
			return ResultUtil.success(reJson);
		}
		return result;
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdQueryPerson)
	public Result queryPerson(@Validated @RequestBody QueryPersonRequest request, BindingResult bindingResult) {

		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#queryPerson",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());


		if (null == request.getPId() && StringUtils.isNotBlank(request.getCardNo())) {
			Result result = payConfigClientService.getCardInfoByCardNo(comId, request.getCardNo());
			if(result.getCode()!=200){
				return result;
			}
			EntityCardInfo entityCardInfo  = JSON.parseObject(JSON.toJSONString(result.getData()), EntityCardInfo.class);
			request.setPId(entityCardInfo.getPId().intValue());
		}

		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setComId(comId);
		userInfoVo.setOnlyOne(true);
		userInfoVo.setPCode(request.getPCode());
		userInfoVo.setPId(request.getPId());
		userInfoVo.setPPhone(request.getPPhone());

		Result personResult = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
		if (200 == personResult.getCode() && null != personResult.getData()) {
			UserInfoVo2 userInfoVo2 = JSON.parseObject(JSON.toJSONString(personResult.getData()), UserInfoVo2.class);
			Result xfUserInfoResult = humanFeignService.getXfUserInfo(userInfoVo2.getComId(), userInfoVo2.getPId());
			if (200 == xfUserInfoResult.getCode() && null != xfUserInfoResult.getData()) {
				XfUserInfoVo xfUserInfoVo = JSON.parseObject(JSON.toJSONString(xfUserInfoResult.getData()), XfUserInfoVo.class);
				userInfoVo2.setAccTypeId(xfUserInfoVo.getAccTypeId());
			}
			return ResultUtil.success(userInfoVo2);
		} else {
			return ResultUtil.error(ResultEnum.Err_1001);
		}
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdQueryWallet)
	public Result queryWallet(@Validated @RequestBody QueryWalletRequest request, BindingResult bindingResult) {

		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#queryWallet",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		if (StringUtils.isNotBlank(request.getPCode()) && StringUtils.isBlank(request.getCardNo()) && null == request.getPId()) {
			UserInfoVo userInfoVo = new UserInfoVo();
			userInfoVo.setOnlyOne(true);
			userInfoVo.setComId(comId);
			userInfoVo.setPCode(request.getPCode());
			Result result = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
			if (200 == result.getCode() && null != result.getData()) {
				EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result.getData()), EntityPersonnelInfo.class);
				request.setPId(entityPersonnelInfo.getPId());
			}
		}
		Map<String, Object> balance = new HashMap<>();
		balance.put("companyID", comId);
		balance.put("type", (null != request.getPId() && request.getPId() > 0) ? 3 : 1);
		balance.put("cardNum", (null != request.getPId() && request.getPId() > 0) ? request.getPId() : request.getCardNo());

		RespMachMessage respMachMessage = payHandleClientService.getBalance(balance);
		if (respMachMessage.getCode().equals("0000")) {
			return ResultUtil.success(JSON.parseObject(JSON.toJSONString(respMachMessage.getData())));
		} else {
			return ResultUtil.error(ResultEnum.Err_3044);
		}
	}

	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdConsWallet)
	public Result consWallet(@Validated @RequestBody ConsWalletRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#consWallet",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		if (StringUtils.isNotBlank(request.getPCode()) && StringUtils.isBlank(request.getCardNo()) && null == request.getPId()) {
			UserInfoVo userInfoVo = new UserInfoVo();
			userInfoVo.setOnlyOne(true);
			userInfoVo.setComId(comId);
			userInfoVo.setPCode(request.getPCode());
			Result result = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
			if (200 == result.getCode() && null != result.getData()) {
				EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result.getData()), EntityPersonnelInfo.class);
				request.setPId(entityPersonnelInfo.getPId());
			}
		}

		QrCardPayRequest payRequest = new QrCardPayRequest();
		payRequest.setCompanyId(comId);
		payRequest.setMachNo(request.getMachNo());
		payRequest.setTradeNo(request.getTradeNo());
		payRequest.setAmount(Integer.valueOf(request.getAmount()));
		payRequest.setType((null != request.getPId() && request.getPId() > 0) ? 4 : 1);
		payRequest.setAuthCode((null != request.getPId() && request.getPId() > 0) ? request.getPId().toString() : request.getCardNo());

		Result deviceInfo = payConfigClientService.getDeviceInfo(comId, request.getMachNo());
		if (200 == deviceInfo.getCode() && null != deviceInfo.getData()) {
			EntityXfDeviceInfo entityXfDeviceInfo = JSON.parseObject(JSON.toJSONString(deviceInfo.getData()), EntityXfDeviceInfo.class);
			payRequest.setConsType(entityXfDeviceInfo.getConsType());
		}

		return payHandleClientService.getPayCard(payRequest);
	}


	@PostMapping(ExposeApiUrl.URL_ExposeApi_refundWallet)
	public Result refundWallet(@Validated @RequestBody RefundWalletRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#refundWallet",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		FeeRefundRequest feeRefund = new FeeRefundRequest();
		feeRefund.setCompanyId(comId);
		feeRefund.setFeeItemId(0);
		feeRefund.setPId(0);
		feeRefund.setRefundAmount(request.getRefundAmount());
		feeRefund.setOrigTradeNo(request.getOrigTradeNo());
		feeRefund.setTradeNo(request.getTradeNo());
		feeRefund.setCheck(false);
		return payHandleClientService.feeRefund(feeRefund);
	}


	private Result checkSign(String comAppid, String dockApiCode, String requestSign, String requestJson){
		String key = "gkd#comAppid:" + comAppid + "#dockApiCode:" + dockApiCode;
		Object comDockApi = redisUtil.get(key);
		EntityComDockApi entityComDockApi = null;
		if(comDockApi==null){
			GetReplyApiParaRequest getReplyApiParaRequest = new GetReplyApiParaRequest();
			getReplyApiParaRequest.setComAppid(comAppid);
			getReplyApiParaRequest.setDockCode("gkd");
			getReplyApiParaRequest.setDockApiCode(dockApiCode);
			getReplyApiParaRequest.setKeyType(0);
			Result result = companyClientService.getReplyApiPara(getReplyApiParaRequest);
			if (result.getCode() == 200) {
				entityComDockApi = JSON.parseObject(JSON.toJSONString(result.getData()), EntityComDockApi.class);
				redisUtil.set(key,entityComDockApi,3600l*4l);
			}else {
				redisUtil.set(key,"null",60l);
				return result;
			}
		}else{
			if(comDockApi.toString().equals("null")){
				return ResultUtil.error(ResultEnum.Err_3);
			}
			entityComDockApi = (EntityComDockApi)comDockApi;
		}
		SortedMap<String, Object> parameters = JSON.parseObject(requestJson, SortedMap.class);
		String sign1 = SignUtils.createSign(parameters, entityComDockApi.getKey());
		log.info("当前签名【{}】" ,sign1);
		if (!requestSign.toLowerCase().equals(sign1)) {
			return ResultUtil.error(ResultEnum.Err_202);
		}
		return ResultUtil.success(entityComDockApi.getComId());
	}


	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdConsMeal)
	public Result consMeal(@Validated @RequestBody ConsMealRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#consMeal",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		QrCardPayRequest payRequest = new QrCardPayRequest();
		payRequest.setCompanyId(comId);
		payRequest.setMachNo(request.getMachNo());
		payRequest.setTradeNo(request.getTradeNo());
		payRequest.setAmount(request.getAmount());
		payRequest.setType(7);
		payRequest.setAuthCode(request.getPId().toString());
		payRequest.setConsDate(request.getConsDate());
		payRequest.setConsMeal(request.getConsMeal());
		payRequest.setConsState(5);

		Result deviceInfo = payConfigClientService.getDeviceInfo(comId, request.getMachNo());
		if (200 == deviceInfo.getCode() && null != deviceInfo.getData()) {
			EntityXfDeviceInfo entityXfDeviceInfo = JSON.parseObject(JSON.toJSONString(deviceInfo.getData()), EntityXfDeviceInfo.class);
			payRequest.setConsPoint(entityXfDeviceInfo.getPointId());
		}

		return payHandleClientService.getPayCard(payRequest);
	}


	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdRefundMeal)
	public Result refundMeal(@Validated @RequestBody RefundMealRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#refundMeal",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		QrCodeRefundRequest qrCodeRefundRequest=new QrCodeRefundRequest();
		try {
			qrCodeRefundRequest.setMachNo(request.getMachNo());
			qrCodeRefundRequest.setCompanyId(comId);
			qrCodeRefundRequest.setTradeNo(request.getTradeNo());
			qrCodeRefundRequest.setOrigTradeNo(request.getOrigTradeNo());
			qrCodeRefundRequest.setRefundAmount(request.getAmount());
		}catch (Exception e){
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,异常:【{}】","设备交易号退款 gkd",request.getAmount(),request,e);
			return ResultUtil.error(ResultEnum.Err_4003);
		}
		Result result=payHandleClientService.qrCodeRefund(qrCodeRefundRequest);
		if (result.getCode()!=200){
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,返回:【{}】","设备交易号退款 gkd",request.getMachNo(),request, result);
		}
		return result;
	}



	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdQueryMealOrder)
	public Result queryMealOrder(@Validated @RequestBody QueryMealRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#queryMealOrder",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}
		Long comId = Long.valueOf(checkResult.getData().toString());

		QrCodeQueryRequest qrCodeQueryRequest=new QrCodeQueryRequest();
		try {
			qrCodeQueryRequest.setMachNo(request.getMachNo());
			qrCodeQueryRequest.setCompanyId(comId);
			qrCodeQueryRequest.setTradeNo(request.getTradeNo());
		}catch (Exception e){
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,异常:【{}】","强在线订单查询 gkd",request.getMachNo(),request,e);
			return ResultUtil.error(ResultEnum.Err_4003);
		}
		Result result=payHandleClientService.onlinePayQuery(qrCodeQueryRequest);
		if (result.getCode()!=200){
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,返回:【{}】","强在线订单查询 gkd",request.getMachNo(),request, result);
		}
		return result;
	}





	@PostMapping(ExposeApiUrl.URL_ExposeApi_gkdGzhMsgPush)
	public Result gzhMsgPush(@Validated @RequestBody MJGzhMsgRequest request, BindingResult bindingResult) {
		String sign = request.getSign();
		request.setSign("");
		Result checkResult = checkSign(request.getComId(),"gkd#gzhMsgPush",sign, JSON.toJSONString(request));
		if (200 != checkResult.getCode()) {
			return checkResult;
		}

		Long comId = Long.valueOf(checkResult.getData().toString());

		UserInfoVo userInfoVo = new UserInfoVo();
		userInfoVo.setComId(comId);
		userInfoVo.setPCode(request.getPCode());
		userInfoVo.setOnlyOne(true);
		Result result1 = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
		if (result1.getCode() != 200) {
			return result1;
		}
		EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(result1.getData()), EntityPersonnelInfo.class);

		GzhMsgRequest gzhMsgRequest =new GzhMsgRequest();
		gzhMsgRequest.setComId(comId);
		gzhMsgRequest.setPId(entityPersonnelInfo.getPId());
		gzhMsgRequest.setMerchId(0l);

		GzhMsgParam gzhMsgParam =new GzhMsgParam();
		gzhMsgParam.setUserName(entityPersonnelInfo.getPName());
		gzhMsgParam.setPointName(request.getDormName());
		gzhMsgParam.setPayTime(request.getOpenTime());
		gzhMsgParam.setPic(request.getPic());



		if(request.getStatus() == 0){
			gzhMsgRequest.setType(3);
		}else {
			gzhMsgRequest.setType(4);
			if(request.getStatus()==1){
				gzhMsgParam.setStatus("进入校园");
			}else if (request.getStatus()==2){
				gzhMsgParam.setStatus("离开校园");
			}
		}

		gzhMsgRequest.setParams(gzhMsgParam);
		Result result = mqSimple.gzhMsg(gzhMsgRequest);

		if (result.getCode()!=200){
			log.info("请求方式:【{}】,机器号:【{}】,请求参数:【{}】,返回:【{}】","公众号门禁消息 gkd",request.getComId(),request, result);
		}
		return result;
	}


}
